const config = require("../config")
const http = require("../http")
const yaml = require("js-yaml");
const path = require('path');
const fs = require('fs');


class Utils {

    // 存储 Nacos上 服务列表 的服务名称
    ServiceNameList = []

    constructor() {
        this.getServiceName()
    }

    /**
     * 获取Nacos上的服务名称数组
     * @returns {Promise<void>}
     */
    async getServiceName() {
        console.log("1: [getServiceName] 从Nacos 获取服务名..")
        const {doms} = await http.get({
            url: config.nacosApi.apiList.serviceList,
            data: {pageNo: 1, pageSize: 20},
        });
        if (doms.length === 0) {
            throw new Error("No service found for service list");
        }
        this.serviceName = doms;
        console.log("2: [getServiceName] 服务名为：", this.serviceName)
        await this.generateTraefikConfig()
    }

    /**
     * 从 Nacos 获取服务实例
     * @param serviceName
     * @returns {Promise<*|*[]>}
     */
    async getServiceInstances(serviceName) {
        const {hosts} = await http.get({
            url: config.nacosApi.apiList.instanceInfo,
            data: {serviceName, namespaceId: config.nacosConfig.nameSpace},
        });
        return hosts || []
    }


    /**
     * 生成 traefik 动态配置
     * @returns {Promise<void>}
     */
    async generateTraefikConfig() {
        const traefikConf = {
            http: {
                routers: {},
                services: {},
                middlewares: config.traefikConfig.middlewaresConfig,
            }
        };

        for (const serviceName of this.serviceName) {
            const instances = await this.getServiceInstances(serviceName);
            if (instances.length === 0) {
                console.warn(`服务 ${serviceName} 无可用实例`);
                continue;
            }

            // 1. 配置服务（服务名 + 实例列表）
            traefikConf.http.services[`${serviceName}-service`] = {
                loadBalancer: {
                    servers: instances.map(inst => ({
                        url: `http://${inst.ip}:${inst.port}`,
                    })),
                }
            };

            // 2. 配置路由（路径前缀 + 绑定服务）
            traefikConf.http.routers[`${serviceName}-router`] = {
                rule: `PathPrefix(\`/${serviceName}\`)`, // 如 /main、/product
                service: `${serviceName}-service`,
                entryPoints: ['web'],
                // 应用中间件（压缩、IP白名单、限流、重试等）
                middlewares: config.traefikConfig.middlewaresStr,
            };
        }

        this.stringToYaml(traefikConf)
    }

    /**
     * 生成 yaml 配置文件
     * @param conf
     */
    stringToYaml(conf) {
        console.log("3: [stringToYaml] 生成配置：", JSON.stringify(conf, null, 2));
        console.log()
        console.log()

        const yamlString = yaml.dump(conf, {
            indent: 2,        // 缩进空格数
            skipInvalid: true, // 跳过无效类型
            noRefs: true      // 禁止引用（防止循环引用问题）
        });
        fs.writeFileSync(config.filePath, yamlString, "utf8");
    }
}

module.exports = Utils